import { type ConfigEnv, type UserConfig, defineConfig } from 'vite';
import Vue from '@vitejs/plugin-vue';
import { author, copyright } from './package.json';
import Banner from 'vite-plugin-banner';
import Components from 'unplugin-vue-components/vite';
import AutoImport from 'unplugin-auto-import/vite';
import Icons from 'unplugin-icons/vite';
import IconsResolver from 'unplugin-icons/resolver';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
import { resolve } from 'node:path';
import VueDevTools from 'vite-plugin-vue-devtools';
import { useVitePWA } from './vite/pwaOption';
import { cssOption } from './vite/cssOption';
import { FileSystemIconLoader } from 'unplugin-icons/loaders';
import { rollupOption } from './vite/rollupOption';
import { formatDateTimeStr } from './src/utils/time';
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
import { svgIconPathOption } from './vite/svgIconPathOption';
import { useViteCompression } from './vite/compression';
import { viteAutoDeployPlugin } from 'vite-auto-deploy';
import { elementPlusStyleOptimizeIncludes, optimizeIncludes } from './vite/optimizeDeps';

export const SYSTEM_ENVIRONMENT: Record<string, Record<'flag' | 'name' | 'url', string>> = {
  // 投放系统
  'toufangxitong': {
    name: '投放',
    url: 'https://tf.daishubobo.com',
    flag: 'toufangxitong',
  },
};

export default defineConfig(async ({ command, isPreview, mode }: ConfigEnv): Promise<UserConfig> => {
  process.env.NODE_ENV = SYSTEM_ENVIRONMENT[mode] ? SYSTEM_ENVIRONMENT[mode].flag : process.env.NODE_ENV;
  /** elementPlus导入的样式是css还是scss */
  const elementPlusStyleType: 'css' | 'scss' = 'scss';
  /** 是不是生产环境(预览环境也不是生产环境) */
  const isBuild = Boolean(command === 'build');
  /** svg-icon图片的路径 */
  const svgIconsPath = resolve(__dirname, 'src/assets/svg-icons/vite-plugin-svg-icons');
  /** 需要预构建的依赖 */
  const optimize = [
    'mitt',
    'sortablejs',
    'element-plus',
    'element-plus/es',
    'vue-slicksort',
    'cropperjs',
    '@formkit/auto-animate/vue',
    'qiniu-js',
    'hash-wasm',
    'echarts/core',
    'echarts/components',
    'echarts/charts',
    'echarts/renderers',
  ];
  const config: UserConfig = {
    base: '/', // 基础路径
    plugins: [
      VueDevTools({}),
      Vue(),

      // 自动导入API
      AutoImport({
        dirs: ['./vite/auto-import', './src/pinia/modules'], // 自动导入目录下的模块导出
        imports: ['vue', 'vue-router'],
        vueTemplate: true, // Vue模板内自动导入
        dts: './src/types/auto-imports.d.ts', // 当本项目安装 typescript 时是否 生成相应的 .d.ts 文件 [支持自定义路径] 当设置为true时，默认生成文件到'./auto-imports.d.ts'中
        resolvers: [
          // // 自动导入 Element Plus 相关函数，如：ElMessage, ElMessageBox... (带样式)
          ElementPlusResolver({ importStyle: elementPlusStyleType === 'scss' ? 'sass' : 'css' }),
        ],
      }),
      // 自动注册组件
      Components({
        resolvers: [
          // 自动导入 Element Plus 组件
          ElementPlusResolver({ importStyle: elementPlusStyleType === 'scss' ? 'sass' : 'css' }),
          // 自动注册图标组件
          IconsResolver({ prefix: 'Icon', enabledCollections: ['ep', 'ic', 'solar', 'line-md', 'fluent-emoji', ' prime'], customCollections: ['my'] }),
        ],
        version: 3,
        dts: './src/types/components.d.ts',
      }),
      // 注册 svgIcon
      Icons({
        autoInstall: true,
        scale: 1.2,
        compiler: 'vue3',
        customCollections: { my: FileSystemIconLoader(resolve(__dirname, 'src/assets/svg-icons/unplugin-icons')) },
      }),
      createSvgIconsPlugin({ iconDirs: [svgIconsPath], symbolId: 'icon-[dir]-[name]' }),
      // 生成vite-plugin-svg-icons所需的文件路径类型
      svgIconPathOption({ iconDirs: svgIconsPath, interfaceName: 'BaseSvgIconPath', dts: './src/types/svg-icons-dts.d.ts' }),
      // 注册 PWA 应用
      useVitePWA(),
      /** 压缩 */
      useViteCompression(isBuild),
      viteAutoDeployPlugin({
        /** 上传地址 */
        uploadUrl: 'https://res.daishubobo.com/mywl_asset_server/zip/upload',
        /** 项目名称 (如果多个项目都是用的同上传地址时，服务端可用此字段区分是哪一个项目) */
        projectName: mode === 'toufangxitong' ? 'toufangxitong' : 'mywl_dsdj_admin',
        /** 上传完成后,是否保留压缩包到本地 */
        saveLocalZip: true,
        /** 是否开启自动部署 */
        autoDeploy: isBuild,
      }),
    ],

    resolve: { alias: { '@': resolve(__dirname, 'src') } },

    css: cssOption(elementPlusStyleType), // css配置
    // 预构建
    optimizeDeps: {
      // 需要预构建的依赖
      include: [...(await optimizeIncludes(optimize)), ...(await elementPlusStyleOptimizeIncludes(elementPlusStyleType))],
    },
    server: {
      open: isBuild || isPreview ? (mode === 'toufangxitong' ? 'https://tf.daishubobo.com' : 'https://admin.daishubobo.com') : true, // 是否自动打开浏览器
      host: true, // 服务器主机名,如果允许外部访问,可设置为"0.0.0.0"或者true
      strictPort: false, // 设为 true 时若端口已被占用则会直接退出,而不是尝试下一个可用端口。
      cors: true, // 为开发服务器配置 CORS。默认启用并允许任何源
    },
    define: {
      __APP_VERSION_TIMESTAMP__: JSON.stringify(new Date().getTime()), // 编译时间
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
    },
    esbuild: {
      drop: isBuild ? ['console', 'debugger'] : [], // 清除console和debugger
    },

    build: {
      cssCodeSplit: true, // 启用/禁用 CSS 代码拆分。当启用时,在异步 chunk 中导入的 CSS 将内联到异步 chunk 本身,并在其被加载时插入。 如果禁用,整个项目中的所有 CSS 将被提取到一个 CSS 文件中。
      sourcemap: false, // 构建后是否生成 source map 文件。如果为 true,将会创建一个独立的 source map 文件
      target: 'modules', // 设置最终构建的浏览器兼容目标。默认值是一个 Vite 特有的值——'modules'  还可设置为 'es2015' 'es2016'等
      chunkSizeWarningLimit: 850, // 单位kb  打包后文件大小警告的限制 (文件大于此此值会出现警告)
      assetsInlineLimit: 4096, // 单位字节(1024等于1kb) 小于此阈值的导入或引用资源将内联为 base64 编码,以避免额外的 http 请求。设置为 0 可以完全禁用此项。
      minify: 'esbuild', // 'terser' 相对较慢,但大多数情况下构建后的文件体积更小。'esbuild' 最小化混淆更快但构建后的文件相对更大(大1%——2%)。
      rollupOptions: rollupOption(), // 自定义底层的 Rollup 打包配置
    },
  };

  if (isBuild) {
    /** 添加版权信息 */
    const tannerText = `/**\n *  版权: ${copyright}\n *  作者: ${author}\n *  日期: ${formatDateTimeStr()}\n */`;
    config.plugins?.push(Banner(tannerText));
  }

  return Promise.resolve(config);
});
